#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="Cylinders.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2007, 2008, 2009, 2010, 2011
//       Roland Rosenkranz (Glatzemann@email.de)
//
//    Based on libnoise by Jason Bevins
//      Copyright (C) 2003, 2004 Jason Bevins (licensed under LGPL)
// </copyright>
// <license>
//   This file is part of starLiGHT.Noise.
//
//   starLiGHT.Noise is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   starLiGHT.Noise is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public License
//   along with starLiGHT.Noise. If not, see http://www.gnu.org/licenses/.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.Noise are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 10385                 $:  Revision of last commit *
// * $Author:: unknown            $:  Author of last commit   *
// * $Date:: 2011-06-14 07:59:17 #$:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.Noise.Noise
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;

    #endregion

    /// Noise module that outputs concentric cylinders.
    ///
    /// @image html modulecylinders.png
    ///
    /// This noise module outputs concentric cylinders centered on the origin.
    /// These cylinders are oriented along the @a y axis similar to the
    /// concentric rings of a tree.  Each cylinder extends infinitely along
    /// the @a y axis.
    ///
    /// The first cylinder has a radius of 1.0.  Each subsequent cylinder has
    /// a radius that is 1.0 unit larger than the previous cylinder.
    ///
    /// The output value from this noise module is determined by the distance
    /// between the input value and the the nearest cylinder surface.  The
    /// input values that are located on a cylinder surface are given the
    /// output value 1.0 and the input values that are equidistant from two
    /// cylinder surfaces are given the output value -1.0.
    ///
    /// An application can change the frequency of the concentric cylinders.
    /// Increasing the frequency reduces the distances between cylinders.  To
    /// specify the frequency, call the SetFrequency() method.
    ///
    /// This noise module, modified with some low-frequency, low-power
    /// turbulence, is useful for generating wood-like textures.
    ///
    /// This noise module does not require any source modules.
    public class Cylinders : Module
    {
        /// Frequency of the concentric cylinders.
        protected double frequency;

        /// Default frequency value for the noise::module::Cylinders noise module.
        private const double DEFAULTCYLINDERSFREQUENCY = 1.0;

        /// Constructor.
        ///
        /// The default frequency is set to
        /// noise::module::DEFAULT_CYLINDERS_FREQUENCY.
        public Cylinders() : base(0)
        {
            this.frequency = DEFAULTCYLINDERSFREQUENCY;
        }

        /// Returns the frequency of the concentric cylinders.
        ///
        /// @returns The frequency of the concentric cylinders.
        ///
        /// Increasing the frequency increases the density of the concentric
        /// cylinders, reducing the distances between them.
        public double GetFrequency()
        {
          return this.frequency;
        }

        public override double GetValue(double x, double y, double z, double lowerXBound, double upperXBound, double lowerZBound, double upperZBound)
        {
            x *= this.frequency;
            z *= this.frequency;

            double distFromCenter = Math.Sqrt((x * x) + (z * z));
            double distFromSmallerSphere = distFromCenter - Math.Floor(distFromCenter);
            double distFromLargerSphere = 1.0 - distFromSmallerSphere;
            double nearestDist = Math.Min(distFromSmallerSphere, distFromLargerSphere);
            return 1.0 - (nearestDist * 4.0); // Puts it in the -1.0 to +1.0 range.
        }

        /// Sets the frequenct of the concentric cylinders.
        ///
        /// @param frequency The frequency of the concentric cylinders.
        ///
        /// Increasing the frequency increases the density of the concentric
        /// cylinders, reducing the distances between them.
        public void SetFrequency(double frequency)
        {
          this.frequency = frequency;
        }
    }
}

